[bits 32] ; 切换到32位模式

start:
xor eax, eax ; eax = 0

; 初始化段寄存器, 段地址全部设为0
mov ds, eax
mov ss, eax
mov es, eax
mov fs, eax
mov gs, eax

; 初始化栈指针
mov esp, 0x7c00
mov ax, 0xb800
mov gs, ax
mov ah, 0x07 ; 黑底白字
mov al, ' ' ; clean screen
mov ebx, 0
loop1:
cmp ebx, 2000 ; 8025=2000
jge endloop1
mov [gs:4ebx], eax ; 32位模式下每个字符占4个字节
add ebx, 1
jmp loop1

; student_num_set
endloop1:
mov eax, 0x20323134 ; "2143"
mov [gs:4*36], eax

mov eax, 0x30323132 ; "0212"
mov [gs:4*40], eax

mov eax, 0x33343331 ; "3413"
mov [gs:4*44], eax

mov eax, 0x31393239 ; "1929"
mov [gs:4*48], eax
; 设置GDT表
lgdt [gdt_descriptor]

; 进入保护模式
mov eax, cr0
or eax, 0x1 ; 设置PE位
mov cr0, eax

jmp CODE_SEG:start_protected_mode ; 跳转到保护模式下的代码段
[BITS 32]
start_protected_mode:
; 初始化段寄存器
mov ax, DATA_SEG
mov ds, ax
mov ss, ax
mov es, ax
mov fs, ax
mov gs, ax

; 初始化栈指针
mov esp, 0x80000

; 打印提示信息
mov eax, 0xb8000
mov gs, ax
mov ah, 0x0f ; 白底黑字
mov al, 'P'
mov [gs:2*0], eax
mov al, 'r'
mov [gs:2*1], eax
mov al, 'o'
mov [gs:2*2], eax
mov al, 't'
mov [gs:2*3], eax
mov al, 'e'
mov [gs:2*4], eax
mov al, 'c'
mov [gs:2*5], eax
mov al, 't'
mov [gs:2*6], eax
mov al, 'e'
mov [gs:2*7], eax
mov al, 'd'
mov [gs:2*8], eax
mov al, ' '
mov [gs:2*9], eax
mov al, 'M'
mov [gs:2*10], eax
mov al, 'o'
mov [gs:2*11], eax
mov al, 'd'
mov [gs:2*12], eax
mov al, 'e'
mov [gs:2*13], eax
mov al, '.'
mov [gs:2*14], eax

; 无限循环
jmp $
; GDT表
gdt_start:
; 空描述符
dd 0 ; 段界限
dd 0 ; 段基址
gdt_code:
; 代码段描述符
dw 0xffff ; 段界限
dw 0x0 ; 段基址
db 0x0 ; 段基址
db 10011010b ; 访问标志位
db 11001111b ; 其他标志位
db 0x0 ; 段基址
gdt_data:
; 数据段描述符
dw 0xffff ; 段界限
dw 0x0 ; 段基址
db 0x0 ; 段基址
db 10010010b ; 访问标志位
db 11001111b ; 其他标志位
db 0x0 ; 段基址
gdt_end:
gdt_descriptor:
dw gdt_end - gdt_start - 1 ; GDT表的界限
dd gdt_start ; GDT表的基址

; 常量定义
DATA_SEG equ gdt_data - gdt_start ; 数据段选择子
CODE_SEG equ gdt_code - gdt_start ; 代码段选择子

times 510 - ($ - $$) db 0
db 0x55, 0xaa ; 引导扇区标志